﻿#include "Measure_Trapezoid.h"
#include "qdebug.h"
#include "QTime"
Measure_Trapezoid::Measure_Trapezoid()
{

}
int Measure_Trapezoid::M_Trapezoid(HObject Img, HTuple &OutPara, HObject &OutImg)
{
    QTime time;

    time.start();
    //ok=0;ng=1;abn=-1;不检测不显示=2
    int flag=0;
    OutPara.Clear();

    Flag1=true;
    Flag2=true;
    Flag3=true;
    Flag4=true;
    HObject  Region, RegionT,Rectangle, RegionDifference1,ImageReduced, Region2;
    HObject  ConnectedRegions, SelectedRegions;

    HObject  Rectangle1, ImageReduced1;
    HObject  Region3, RegionTrans, RegionDifference;
    HObject  Rectangle4, RegionErosion, ConnectedRegions3;
    HObject  SelectedRegions1, RegionTrans1,ObjectSelected1,ObjectSelected2;
    HObject  ImageReduced11,ImageReduced22,Edges1,Edges2;


    // Local control variables
    HTuple  Row1,Column1, Phi, W1, H1, R, C, P;
    HTuple  W, H, Line1, Line2, MetrologyHandle1,line1,line2;
    HTuple  Index1,MetrologyHandle2,Distance1,Distance2,Parallel;
    HTuple  Angle1,Angle2;
    HTuple Length1,Length2,Max1,Max2,Indices1,Indices2,Phi1,Phi2,PHI,angle,Len;
    //图像换算比例
    float para1=m_part.para1;
    //高度补偿值
    float para2=m_part.para2;
    //高度标准值
    float para3=m_part.para3;
    //高度下限偏差值
    float para4=m_part.para4;
    //高度上限偏差值
    float para5=m_part.para5;


    //平行度补偿值
    float para6=m_part.para6;
    //平行度标准值
    float para7=m_part.para7;
    //平行度偏差值
    float para8=m_part.para8;




    //角度1补偿值
    float para9=m_part.para9;
    //角度2补偿值
    float para10=m_part.para10;

    //角度1标准值
    float para11=m_part.para11;
    //角度2标准值
    float para12=m_part.para12;

    //角度1下限偏差值
    float para13=m_part.para13;
    //角度2下限偏差值
    float para14=m_part.para14;


    //角度1上限偏差值
    float para15=m_part.para15;
    //角度2上限偏差值
    float para16=m_part.para16;


    //定位阈值
    float para17=m_part.para17;
    //找边sigma
    float para18=m_part.para18;
    //找边阈值
    float para19=m_part.para19;
    try
    {
        OutImg=Img;


        Threshold(Img, &Region, 0, para17);
        Connection(Region,&Region);
        SelectShape(Region, &Region, "area", "and", 1000, 99999999);
        Union1(Region, &Region);
//        FillUp(Region, &Region);

        ShapeTrans (Region, &RegionT, "convex");
        ErosionRectangle1 (RegionT, &RegionT, 11, 11);
        Difference (RegionT, Region, &RegionDifference1);
        PaintRegion (RegionDifference1, Img, &Img, 0, "fill");

        SmallestRectangle2(Region, &Row1, &Column1, &Phi, &W1, &H1);
        GenRectangle2(&Rectangle, Row1, Column1, 0, W1/3, H1+80);
        ReduceDomain(Img, Rectangle, &ImageReduced);
        Threshold(ImageReduced, &Region2, 0, para17);
        Connection(Region2, &ConnectedRegions);
        SelectShape(ConnectedRegions, &SelectedRegions, "area", "and", 550, 99999999);
        Union1(SelectedRegions,&SelectedRegions);
        SmallestRectangle2(SelectedRegions, &R, &C, &P, &W, &H);
        line1.Clear();
        line1.Append(R-H);
        line1.Append(C-W);
        line1.Append(R-H);
        line1.Append(C+W);

        line2.Clear();
        line2.Append(R+H);
        line2.Append(C-W);
        line2.Append(R+H);
        line2.Append(C+W);


        CreateMetrologyModel(&MetrologyHandle1);
        AddMetrologyObjectLineMeasure(MetrologyHandle1, HTuple(line1[0]), HTuple(line1[1]),
                HTuple(line1[2]), HTuple(line1[3]), 20, 5, para18, para19, HTuple(), HTuple(),
                &Index1);
        ApplyMetrologyModel(Img, MetrologyHandle1);
        GetMetrologyObjectResult(MetrologyHandle1, "all", "all", "result_type", "all_param",
                                 &Line1);
        ClearMetrologyModel(MetrologyHandle1);

        CreateMetrologyModel(&MetrologyHandle2);
        AddMetrologyObjectLineMeasure(MetrologyHandle2, HTuple(line2[0]), HTuple(line2[1]),
                HTuple(line2[2]), HTuple(line2[3]), 20, 5, para18, para19, HTuple(), HTuple(),
                &Index1);
        ApplyMetrologyModel(Img, MetrologyHandle2);
        GetMetrologyObjectResult(MetrologyHandle2, "all", "all", "result_type", "all_param",
                                 &Line2);
        ClearMetrologyModel(MetrologyHandle2);


        //计算边长
        DistancePl(HTuple(Line1[0]), HTuple(Line1[1]), HTuple(Line2[0]), HTuple(Line2[1]),
                HTuple(Line2[2]), HTuple(Line2[3]), &Distance1);
        DistancePl(HTuple(Line1[2]), HTuple(Line1[3]), HTuple(Line2[0]), HTuple(Line2[1]),
                HTuple(Line2[2]), HTuple(Line2[3]), &Distance2);
        Len=(Distance1+Distance2)/2;
        qDebug()<<Len.D()<<"11111111111111";
        Len=Len*para1+para2;
        if(!((Len>(para3-para4))&&(Len<(para3+para5))))
        {
            flag=1;
            Flag1=false;
        }


        //计算平行度
        AngleLl(HTuple(Line1[0]), HTuple(Line1[1]), HTuple(Line1[2]), HTuple(Line1[3]),
                HTuple(Line2[0]), HTuple(Line2[1]), HTuple(Line2[2]), HTuple(Line2[3]),
                &Parallel);



        Parallel = ((Parallel*180)/PI).TupleAbs()+para6;
//        qDebug()<<Parallel.D();
        //长边
        if(!(Angle1<(para7+para8)))
        {
            Flag2=false;
            flag=1;
        }
        GenRectangle2(&Rectangle1, Row1, Column1, Phi, W1, H1);
        ReduceDomain(Img, Rectangle1, &ImageReduced1);
        Threshold(ImageReduced1, &Region3, 0, para17);

        ShapeTrans(Region3, &RegionTrans, "rectangle2");

        Difference(RegionTrans, Region3, &RegionDifference);
        GenRectangle1(&Rectangle4, 0, 0, 1, 1);
        Erosion1(RegionDifference, Rectangle4, &RegionErosion, 8);
        Connection(RegionErosion, &ConnectedRegions3);
        SelectShape(ConnectedRegions3, &SelectedRegions1, "area", "and", 2000, 9999999);

        ShapeTrans(SelectedRegions1, &RegionTrans1, "rectangle1");
        ErosionRectangle1(RegionTrans1,&RegionTrans1,10,10);


        SelectObj(RegionTrans1,&ObjectSelected1,1);
        ReduceDomain(Img,ObjectSelected1,&ImageReduced11);
        EdgesSubPix(ImageReduced11,&Edges1,"canny",1,10,50);
        SelectShapeXld(Edges1, &Edges1, (HTuple("circularity").Append("contlength")),
                       "and", (HTuple(0).Append(110)), (HTuple(0.011).Append(170)));
        LengthXld(Edges1, &Length1);
        TupleMax(Length1, &Max1);
        TupleFind(Length1, Max1, &Indices1);
        SelectObj(Edges1, &Edges1, Indices1+1);

        SelectObj(RegionTrans1, &ObjectSelected2, 2);
        ReduceDomain(Img, ObjectSelected2, &ImageReduced22);
        EdgesSubPix(ImageReduced22, &Edges2, "canny", 1, 10, 50);
        SelectShapeXld(Edges2, &Edges2, (HTuple("circularity").Append("contlength")),
                       "and", (HTuple(0).Append(110)), (HTuple(0.011).Append(170)));
        LengthXld(Edges2, &Length2);
        TupleMax(Length2, &Max2);
        TupleFind(Length2, Max2, &Indices2);
        SelectObj(Edges2, &Edges2, Indices2+1);

        OrientationXld(Edges1, &Phi1);
        OrientationXld(Edges2, &Phi2);
        TupleConcat(Phi1, Phi2, &PHI);
        PHI = (180*PHI)/PI;
        TupleAbs(PHI, &PHI);

        for(int i=0;i<=1;i++)
        {
            if((PHI[i]>135)&&(PHI[i]<180))
            {
                TupleConcat(angle, 180-HTuple(PHI[i]), &angle);
            }
            else if((PHI[i]>45)&&(PHI[i]<90))
            {
                TupleConcat(angle, 90-HTuple(PHI[i]), &angle);
            }
            else if((PHI[i]<135)&&(PHI[i]>90))
            {
                TupleConcat(angle, HTuple(PHI[i]-90), &angle);
            }
            else
            {
                TupleConcat(angle, HTuple(PHI[i]), &angle);
            }
        }
        Angle1=angle[0]+para9;
        Angle2=angle[1]+para10;
        if(!((Angle1>(para11-para13))&&(Angle1<(para11+para15))))
        {
            flag=1;
            Flag3=false;
        }
        if(!((Angle2>(para12-para14))&&(Angle2<(para12+para16))))
        {
            flag=1;
            Flag4=false;
        }

        //计算角度
        OutPara.Append(Len).Append(Parallel).Append(Angle1).Append(Angle2);
        qDebug()<<Len.D()<<Parallel.D()<<Angle1.D()<<Angle2.D();

        return flag;


    }
    catch(HException ex)
    {
        flag=-1;
        OutPara.Append(0).Append(0).Append(0).Append(0);
        Flag1=false;
        Flag2=false;
        Flag3=false;
        Flag4=false;
        return flag;
    }

}
